<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Promise测试</title>
</head>
<body>

<script type="text/javascript">
  const first = () => (new Promise((resolve,reject)=>{
    console.log(3);  // 1
    let p = new Promise((resolve, reject)=>{
      console.log(7);  // 2
      setTimeout(()=>{
        console.log(5);
        resolve(6);
      },0)
      resolve(1);
    });
    resolve(2);
    p.then((arg)=>{
      console.log(arg);
    });

  }));

  first().then((arg)=>{
    console.log(arg);
  });
  console.log(4);
</script>


<!--promise的基本使用-->
<!--
<script type="text/javascript">
  var promise = new Promise(function (resolve, reject) {
    setTimeout(function () {
      // resolve('foo')
      reject('xxxx')
    }, 300)
  })

  promise.then(function (value) {
    console.log(value)
  }, function (reason) {
    console.log(reason)
  })

  console.log(promise)
</script>-->

<!--
异步实现方式:
1). 回调
2). promise ==> gernator ==> async/await
-->
<script type="text/javascript">
  // 成功的回调函数
  function successCallback(result) {
    console.log("声音文件创建成功: " + result);
  }

  // 失败的回调函数
  function failureCallback(error) {
    console.log("声音文件创建失败: " + error);
  }

  // 回调: 执行异步处理前就得指定回调函数
  createAudioFileAsync(audioSettings, successCallback, failureCallback)

  // promise: 创建promise对象(内部会立即执行异步处理)后, 再指定回调函数(甚至可以异步处理结束后)
  createAudioFileAsync(audioSettings).then(successCallback, failureCallback);

  const p = new Promise ((resolve, reject) => {

    // 执行异步处理
    axios.get()
  })

  p.then()


</script>

<!--
回调地狱:
解决: 使用promise
-->
<script type="text/javascript">
  doSomething(function(result) {
    doSomethingElse(result, function(newResult) {
      doThirdThing(newResult, function(finalResult) {
        console.log('Got the final result: ' + finalResult);
      }, failureCallback);
    }, failureCallback);
  }, failureCallback);

  doSomething()
    .then(result => doSomethingElse(result))
    .then(newResult => doThirdThing(newResult))
    .then(finalResult => {
      console.log(`Got the final result: ${finalResult}`);
    })
    .catch(failureCallback);
</script>




<!--promise相关代码执行顺序-->
<!--

<script type="text/javascript">
  let p = new Promise((resolve, reject) => { // 同步执行的回调: 内部会立即调用
    console.log('excutor()  resolve/reject()之前')
    if (Date.now() % 2 === 0) {
      resolve('resolve value') // 内部是异步执行的 ==> 状态是异步变化 ===> onResolved回调异步执行

      console.log('excutor()  resolve()之后')
    } else {
      // reject('reject reason')
      throw new Error('error....')
      console.log('excutor()  rejected()之后')
    }
    setTimeout(() => {
      console.log('excutor resolve/reject()之后, timeout')
    })
    console.log('setTimeout()之后')
  })

  setTimeout(() => {
    p.then(value => {
      console.log('onFulfilled', value)
    }, reason => {
      console.log('onRejected', reason)
    })
    console.log('-&#45;&#45;&#45;&#45;&#45;&#45;&#45;&#45;')
  }, 1000)

  console.log('promise.then()之后', p)
</script>
-->

<!--
使用promise简单封装XMLHttpRequest对象(只支持GET)
-->
<!--

<script type="text/javascript">
  const promiseAjax = function (url) {
    return new Promise(function (resolve, reject) {
      const handler = function () {
        if (this.readyState === 4) {
          if (this.status === 200) {
            resolve(this.response) // 解析json得到js对象/数组
          } else {
            reject(new Error(this.statusText))
          }
        }
      }

      const client = new XMLHttpRequest()
      client.open("GET", url)
      client.onreadystatechange = handler
      client.responseType = "json"
      client.setRequestHeader("Accept", "application/json")
      client.send()
    })
  }

  promiseAjax('https://api.github.com/search/users2?q=aa').then(value => {
    console.log('成功了', value)
  }, reason => {
    console.log('失败了', reason)
  })
</script>
-->
<!--
<script type="text/javascript">

  const p1  = new Promise((resolve, reject) => {
    resolve(2)
    // reject(3)
  })
  const p2 = Promise.resolve(2)
  const p3 = Promise.reject(3)


  const p2 = p1.then(val => {
    console.log('p1', val)
    // return 3
    return new Promise ((resolve, reject) => {
      resolve(4)
    })
  })

  p2.then(val => {
    console.log('p2', val)
  })



</script>-->

<!--
一旦异常抛出，promise链就会停下来，直接调用链中的catch处理程序来继续当前执行
-->
<!--
<script type="text/javascript">
  new Promise((resolve, reject) => {
    console.log('excutor() resolve() before')
    resolve()
    console.log('excutor() resolve() after')
  })
    .then(() => {
      console.log('then1 onFulfilled()  error before')
      throw new Error('Something failed')

      console.log('then1 onFulfilled()  error after')
    })
    .then(() => {
      console.log('then2 onFulfilled()')
    })
    .catch(() => {
      console.log('catch onRejected()')
    })
    .then(() => {
      console.log('then3 onRejected()')
    })
</script>-->

<!--
延迟读取异步数据: 在.then()之前promise已变为了fulfilled状态, 后面一旦指定onResolved回调也会异步执行
-->
<!--

<script type="text/javascript">
  // const p1 = Promise.resolve('abc')
  const p1 = new Promise((resolve, reject) => {
    resolve('abc')
  })
  p1.then(value => {
    console.log('0000', value)
  })
  console.log('11', p1)


  setTimeout(() => {
    console.log('22', p1)
  }, 100)

  setTimeout(() => {
    p1.then(value => {
      console.log('onFulFilled()', value)
    }, reason => {
      console.log('onRejected()', reason)
    })
    console.log('then()之后')
  }, 1000)
</script>
-->


<!--
  then()多次调用的2种方式
      1). 一个promise多次调用then()
      2). promise链式多次调用then()
  then()返回的promise对象
-->


<script type="text/javascript">
  // const p = Promise.resolve('abc')
  // const p = Promise.reject('abc')

  // 1). 一个promise多次调用then()
//  p.then(value => {console.log('1111', value)})
//  p.then(value => {console.log('2222', value)})
//  console.log('-------')

  // 2). promise链式多次调用then()
 /* p.then(value => {
    console.log('1111 onFulfilled()', value)
    // return value.toUpperCase()
    // return Promise.resolve('3')
    // throw new Error('异常')
    // throw 4
  }, (reason) => {
    console.log('11111 onRejected()', reason)
  })
  .then(value => {
    console.log('2222 onFulfilled()', value)
  }, reason => {
    console.log('2222 onRejected()', reason)
  })*/
    /*.then(null, reason => {

    })
    .catch(reason => {

    })*/
</script>

<!--
使用
  Promise.resolve()
  Promise.reject()
  Promise.all()
-->
<!--
<script type="text/javascript">
  const p1 = Promise.resolve('abc')
  const p2 = Promise.resolve('efg')
  const p3 = Promise.reject('error')
  Promise.all([p1, p3, p2]).then(values => console.log(values), reason => {console.log(reason)})
</script>
-->

<script type="text/javascript">

</script>


</body>
</html>